package model.optimization;

import model.AbstractModel;
import model.ComputablePart;
import model.ModelPart; 

public abstract class PartOptimizer<T extends AbstractModel>  implements ComputablePart<T>  {

	protected ModelPart modelPart;
	protected int maxIter, iter;
	protected double error, errorThreshold;
	
	protected String name;
	
	public PartOptimizer(String name, ModelPart modelPart) {
		this.modelPart = modelPart;
		this.name = name;
	}
	
	public PartOptimizer() {
	}
	
	public String getName() {
		return "PO";
	}
	
	public void set(String name, ModelPart modelPart) {
		this.modelPart = modelPart;
		this.name = name;
	}
	
	@Override
	public void init() {
		modelPart.init();
		maxIter = 10000; iter = 0;
		error = Double.MAX_VALUE; errorThreshold = 0.01;
	}

	@Override
	public void setParameters() {
		modelPart.setParameters();
	}

	/**
	 * Override this method (and call super.modelComputed()) to do optimization
	 */
	@Override
	public void modelComputed(T model) {
		modelPart.modelComputed(null);
		iter++;
	}
	

	@Override
	public boolean isDone() {
		
		// max iterations?
		if (iter >= maxIter) return true;

		// convergence ?
		if (error < errorThreshold) return true;
		
		return false;
	}

}
